﻿using PlutoStudio.Net.Processors.Attributes;
using PlutoStudio.Net.Messages;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace PlutoStudio.Net.Processors
{
    public class MessageProcessorFactory
    {
        [ImportMany(typeof(IMessageProcessor), AllowRecomposition = true, RequiredCreationPolicy = CreationPolicy.NonShared)]
        private IEnumerable<Lazy<IMessageProcessor, IMessageProcessorMetadata>> processors;

        private static Lazy<MessageProcessorFactory> lazyFactory = new Lazy<MessageProcessorFactory>(()=>new MessageProcessorFactory(), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);

        public static MessageProcessorFactory Factory()
        {
            return new MessageProcessorFactory();
        }
        private MessageProcessorFactory()
        {
           var catalog= new AggregateCatalog(
                new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory),
                new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory,"*.exe")
                );
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }

        public IMessageProcessor CreateProcessor(string config, IMessage message)
        {
            var lazy= processors.LastOrDefault(p => p.Metadata.Code == message.Code && p.Metadata.Catalog == config);
            if (lazy==null)
            {
                return null;
            }
            var type = lazy.Value.GetType();
            return Activator.CreateInstance(type) as IMessageProcessor;
        }
    }
}
